package com.dimao.certificate_build_service.Util.Log;

import com.dimao.certificate_build_service.Util.TimeUtil;
import io.vertx.core.Vertx;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class Log {

    private static Logger logger = LoggerFactory.getLogger("log p");
    private static SaveMode mode = SaveMode.NoSave;
    private static SaveLogMessageHandler handler;
    private static Level level = Level.trace;


    public static void initLogger(Vertx vertx, SaveMode modeArg, Level levelArg){
        setMode(modeArg);
        setLevel(levelArg);
        checkMode(vertx);
    }

    public static void trace(String message) {
        if (checkLevel(Level.trace)) {
            logger.trace(message);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.trace, message));
        }
    }

    public static void debug(String message){
        if (checkLevel(Level.debug)) {
            logger.debug(message);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.debug, message));
        }
    }

    public static void debug(String message, Throwable throwable){
        if (checkLevel(Level.debug)) {
            logger.debug(message, throwable);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.debug, message, throwable));
        }
    }

    public static void info(String message){
        if(checkLevel(Level.info)){
            logger.info(message);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.info, message));
        }
    }


    public static void warn(String message){
        if(checkLevel(Level.warn)){
            logger.warn(message);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.warn, message));
        }
    }

    public static void warn(String message, Throwable throwable){
        if(checkLevel(Level.warn)){
            logger.warn(message, throwable);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.warn, message, throwable));
        }
    }

    public static void error(String message){
        if(checkLevel(Level.error)){
            logger.error(message);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.error, message));
        }
    }

    public static void error(String message, Throwable throwable){
        if(checkLevel(Level.error)){
            logger.error(message, throwable);
        }

        if(handler != null){
            handler.save(makeLogMessage(Level.error, message, throwable));
        }
    }

    private static void checkMode(Vertx vertx){
        switch (mode){
            case Text:{
                handler = new TextLogAction(vertx);
                break;
            }
            case NoSave:
            default:{
                handler = null;
            }
        }
    }

    @Contract(pure = true)
    private static boolean checkLevel(@NotNull Level loggerLevel){
        //当传入等级小于log的全局等级时
        //禁止输出该等级的log日志
        if(loggerLevel.compareTo(Log.level) < 0){
            return false;
        }
        return true;
    }

    @NotNull
    private static String makeLogMessage(@NotNull Level level, String message){
        return new StringBuffer()
                .append(TimeUtil.getCurrentDate(true))
                .append(" [").append(level.toString()).append("]")
                .append(" msg: ").append(message).toString();
    }

    private static String makeLogMessage(Level level, String message, Throwable throwable){
        return new StringBuffer()
                .append(TimeUtil.getCurrentDate(true))
                .append(" [").append(level.toString()).append("]")
                .append(" msg: ").append(message)
                .append(" throwable: ").append(throwable.getMessage()).toString();
    }


    public static void setMode(SaveMode mode) {
        Log.mode = mode;
    }

    public static void setLevel(Level level) {
        Log.level = level;
    }
}
